package algorithm.measures;

import java.text.DecimalFormat;
import java.util.Map;
import java.util.TreeMap;

import utility.file.TextFile;


public class ConfusionMatrix{
	
	private TreeMap<String, TreeMap<String, Integer>> _rowToColumn;

	public ConfusionMatrix(){
//		_rowToColumn = new HashMap<String,Map<String,Integer>>();
		_rowToColumn = new TreeMap<String,TreeMap<String,Integer>>();
	}

	public void incrementValueOn(String trueCategory, String predictedCategory) {
		putRowAndColumn(trueCategory);
		putRowAndColumn(predictedCategory);
		
		TreeMap<String,Integer> rowElement = _rowToColumn.get(trueCategory);
		int currentValue = rowElement.get(predictedCategory);
		currentValue++;
		rowElement.put(predictedCategory, currentValue);
		_rowToColumn.put(trueCategory, rowElement);
	}
	
	public void printAll(){
		for (String eachRow : _rowToColumn.keySet()) {
			System.out.print(eachRow+" ");
			TreeMap<String, Integer> rowElement = _rowToColumn.get(eachRow);
			for (String eachColumn : rowElement.keySet()) {
				System.out.print(rowElement.get(eachColumn)+" ");
			}
			System.out.println();
		}
	}

	private void putRowAndColumn(String name) {
		TreeMap<String,Integer> columnToValue = _rowToColumn.get(name);
		if(columnToValue!=null) return;
		
		columnToValue = new TreeMap<String,Integer>();
		columnToValue.put(name, 0);
		
		for (String each : _rowToColumn.keySet()) {
			columnToValue.put(each, 0);
			TreeMap<String,Integer> currentColumnToValue = _rowToColumn.get(each);
			currentColumnToValue.put(name, 0);
			_rowToColumn.put(each, currentColumnToValue);
		}
		_rowToColumn.put(name, columnToValue);
	}

	public void writeMatrixForOn(int totalInstances, TextFile file) {
		int correctlyClassified = 0;
		int incorrectlyClassified = 0;
		int unclassified = 0;
		StringBuffer firstLine = new StringBuffer("Classi vere\\Classi predette;;");
		for (String each : _rowToColumn.keySet()) {
			firstLine.append(each);
			firstLine.append(";");
		}
		file.putLine(firstLine.toString());
		file.putLine(";;;;;");
		
		for (String each : _rowToColumn.keySet()) {
			StringBuffer resultLine = new StringBuffer(each);
			resultLine.append(";");
			resultLine.append(";");
			Map<String,Integer> columnToValue = _rowToColumn.get(each);
			for (String eachColumn : columnToValue.keySet()) {
				Integer value = columnToValue.get(eachColumn);
				resultLine.append(value);
				resultLine.append(";");
				if(eachColumn.equals(each)) correctlyClassified+=value;
				else incorrectlyClassified+=value;
			}
			file.putLine(resultLine.toString());
		}
		file.putLine(";;;;");
		file.putLine(";;;;");
		unclassified = totalInstances - (correctlyClassified+incorrectlyClassified);
		file.putLine("Istanze classificate correttamente;"+correctlyClassified+";"+percentFor(correctlyClassified,totalInstances));
		file.putLine("Istanze non classificate correttamente;"+incorrectlyClassified+";"+percentFor(incorrectlyClassified,totalInstances));
		file.putLine("Istanze non classificate;"+unclassified+";"+percentFor(unclassified,totalInstances));
		file.putLine("Istanze totali;"+totalInstances);
	}

	private String percentFor(int number, int totalInstances) {
		if(totalInstances==0) return "0%";
		
		DecimalFormat decimalFormat = new DecimalFormat("#.000");
		double ratio = (double)number/totalInstances;
		double percent = ratio*100;
		String percentAsString = decimalFormat.format(percent);
		return percentAsString+"%";
	}

}
